package com.comment.util;

import com.comment.exception.ServiceException;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * jwt工具类
 */
public class JwtUtils {
    // 使用uuid生成密钥
    private final static String secret = "202cb962ac59075b964b07152d234b70";
    // 用户数据的key
    private final static String usernameKey = "usernameKey";

    /**
     * 生成token
     *
     * @param username 用户名
     * @return
     */
    public static String createJwtToken(String username) {
        try {
            // 创建头部对象
            JWSHeader jwsHeader =
                    new JWSHeader.Builder(JWSAlgorithm.HS256)       // 加密算法
                            .type(JOSEObjectType.JWT) // 静态常量
                            .build();

            // 创建载荷
            Map<String, Object> map = new HashMap<String, Object>();
            map.put(usernameKey, username);
            Payload payload = new Payload(map);

            // 创建签名器
            JWSSigner jwsSigner = new MACSigner(secret);// 密钥

            // 创建签名
            JWSObject jwsObject = new JWSObject(jwsHeader, payload);// 头部+载荷
            jwsObject.sign(jwsSigner);// 再+签名部分

            // 生成token字符串
            return jwsObject.serialize();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 验证jwt token是否合法
     *
     * @param jwtStr
     * @return
     */
    public static boolean verify(String jwtStr) {
        try {
            JWSObject jwsObject = JWSObject.parse(jwtStr);
            JWSVerifier jwsVerifier = new MACVerifier(secret);
            return jwsObject.verify(jwsVerifier);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 从token中解析出用户名
     *
     * @param jwtStr token
     * @return 登录人ID和账号
     */
    public static String getUserNameFormJwt(String jwtStr) {
        try {
            JWSObject jwsObject = JWSObject.parse(jwtStr);
            Map<String, Object> map = jwsObject.getPayload().toJSONObject();
            return (String) map.get(usernameKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过token获取登录人id
     *
     * @param jwtStr token
     * @return 登录人ID
     */
    public static Long getUserId(String jwtStr) {
        String userIdAndAccount = getUserNameFormJwt(jwtStr);
        if (userIdAndAccount == null) {
            throw new RuntimeException("token无效");
        }
        return Long.valueOf(userIdAndAccount.split(",")[0]);
    }

    /**
     * 通过token获取登录人id
     *
     * @param jwtStr token
     * @return 登录人ID
     */
    public static Long getPlayerId(String jwtStr) {
        return getUserId(jwtStr);
    }

    public static void main(String[] args) {
        String jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZUtleSI6IjEwMDMsIn0.6k5coCL6XzrXMGhYGYueH8gkN-oIowanpxAoj31Y4EA";
        Long playerId = getPlayerId(jwt);
        System.out.println(playerId);

        String[] split = Objects.requireNonNull(JwtUtils.getUserNameFormJwt(jwt)).split(",");
        if (split.length < 1) {
            throw new ServiceException("玩家id为空");
        }
        System.out.println(Long.valueOf(split[0]));
    }

    /**
     * 通过token获取登录人账号
     *
     * @param jwtStr token
     * @return 登录人账号
     */
    public static String getUserAccount(String jwtStr) {
        String userIdAndAccount = getUserNameFormJwt(jwtStr);
        assert userIdAndAccount != null;
        return userIdAndAccount.split(",")[1];
    }
}